﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using AForge.Video;
using AForge.Video.DirectShow;
using AForge.Vision.Motion;
using AForge.Imaging;
using VideoFlowStatistics.Class;
using System.Threading;

namespace VideoFlowStatistics
{
    public partial class FormMany : Form
    {
        private IVideoSource videoSourceOne = null;
        private IVideoSource videoSourceTwo = null;
        private IVideoSource videoSourceThree = null;

        private static Bitmap ImageOne = null;
        private static Bitmap ImageTwo = null;
        private static Bitmap ImageThree = null;

        private static Bitmap ImageBit = null;
        private Panorama pa;
        //运行分析
        BlobCountingObjectsProcessing monBlob = new BlobCountingObjectsProcessing();
        MotionDetector detector;

        private ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();

        //总人数
        private int[] AllCount = new int[] { };
        private int[] tmpAllCount = new int[] { };

        private int PeopleCountSing = 0;

        //运动分析
        FeatureAnalysis fAnalysis;

        //每帧物体的特征
        private Blob[] RecBlobItems;

        //设定一个添加撞线集合的线程
        private System.Threading.AutoResetEvent TheadReset = new System.Threading.AutoResetEvent(false);
        //视频种类
        private static string vType = "1";//1一个视频，2多个视频

        public FormMany()
        {
            InitializeComponent();
            detector = new MotionDetector(
          new SimpleBackgroundModelingDetector(),
          monBlob);
            fAnalysis = new FeatureAnalysis();
        }

        private void FormMany_Load(object sender, EventArgs e)
        {
            pa = new Panorama();
            //新建一个线程用于处理碰线集合
            Thread tProcess = new Thread(new ThreadStart(Process));
            tProcess.Start();

            ////// 创建视频路径
            //FileVideoSource fileSource1 = new FileVideoSource(@"C:\Users\jiawei\Desktop\多人新场景.avi");
            //FileVideoSource fileSource2 = new FileVideoSource(@"C:\Users\jiawei\Desktop\多人新场景.avi");
            //// 打开视频
            //OpenVideoSource(fileSource1, SlotNo.NoOne);
            //OpenVideoSource(fileSource2, SlotNo.NoTwo);
        }

        #region 打开摄像头或视频

        #region 打开视频
        private void openFile_Click(object sender, EventArgs e)
        {
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                // 创建视频路径
                FileVideoSource fileSource = new FileVideoSource(openFileDialog.FileName);
                 ToolStripMenuItem item = (ToolStripMenuItem)sender;
                 if (item.Name == "openFileOne")
                 {
                     // 打开视频
                     OpenVideoSource(fileSource, SlotNo.NoOne);
                 }
                 else if (item.Name == "openFileTwo")
                 {
                     // 打开视频
                     OpenVideoSource(fileSource, SlotNo.NoTwo);
                 }
                 else if (item.Name == "openFileThree")
                 {
                     // 打开视频
                     OpenVideoSource(fileSource, SlotNo.NoThree);
                 }
            }
        }
        #endregion

        #region 打开摄像头
        private void openLocalVideo_Click(object sender, EventArgs e)
        {
            VideoCaptureDeviceForm form = new VideoCaptureDeviceForm();

            if (form.ShowDialog(this) == DialogResult.OK)
            {
                // 打开视频
                ToolStripMenuItem item = (ToolStripMenuItem)sender;
                if (item.Name == "openLocalVideoOne")
                {
                    OpenVideoSource(form.VideoDevice, SlotNo.NoOne);
                }
                else if (item.Name == "openLocalVideoTwo")
                {
                    OpenVideoSource(form.VideoDevice, SlotNo.NoTwo);
                }
                else if (item.Name == "openLocalVideoThree")
                {
                    OpenVideoSource(form.VideoDevice, SlotNo.NoThree);
                }
            }
        }

        private void openJPEGURLToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FormSelectUrl form = new FormSelectUrl();

            form.Description = "请输入一个JPEG网络摄像头地址:";
            form.URLs = new string[]
				{
					"http://192.168.1.112/image/jpeg.cgi"
				};

            if (form.ShowDialog(this) == DialogResult.OK)
            {

                JPEGStream jpegSource = new JPEGStream(form.URL);

                ToolStripMenuItem item = (ToolStripMenuItem)sender;
                if (item.Name == "openJPEGURLOne")
                {
                    OpenVideoSource(jpegSource, SlotNo.NoOne);
                }
                else if (item.Name == "openJPEGURLTwo")
                {
                    OpenVideoSource(jpegSource, SlotNo.NoTwo);
                }
                else if (item.Name == "openJPEGURLThree")
                {
                    OpenVideoSource(jpegSource, SlotNo.NoThree);
                }
            }
        }

        #endregion

        private void OpenVideoSource(IVideoSource source, string type)
        {
            // 设置鼠标忙碌
            this.Cursor = Cursors.WaitCursor;

            // 开始执行视频显示
            if (type == SlotNo.NoOne)
            {
                videoSourcePlayerOne.VideoSource = new AsyncVideoSource(source);
                videoSourcePlayerOne.Start();

                //打开二号机位
                menuStripTwo.Enabled = true;
                videoSourceOne = source;
            }
            else if (type == SlotNo.NoTwo)
            {
                videoSourcePlayerTwo.VideoSource = new AsyncVideoSource(source);
                videoSourcePlayerTwo.Start();

                //打开三号机位
                menuStripThree.Enabled = true;
                //状态置为2，多视频合成
                vType = "2";

                videoSourceTwo = source;
            }
            else if (type == SlotNo.NoThree)
            {
                videoSourcePlayerThree.VideoSource = new AsyncVideoSource(source);
                videoSourcePlayerThree.Start();

                videoSourceThree = source;
            }
            //Fps统计重置
            //FpsCount.fpsReset();

            //打开计时器
            if (vType == "1")
            {
                timer.Start();
                //设置鼠标变回默认
                this.Cursor = Cursors.Default;
            }
            else
            {
                if (videoSourceOne != null && videoSourceTwo != null)
                {
                    timer.Start();
                    //设置鼠标变回默认
                    this.Cursor = Cursors.Default;
                }
            }
        }
        #endregion

        #region 关闭摄像头或视频
        private void CloseSlot_Click(object sender, EventArgs e)
        {
            // 打开视频
            ToolStripMenuItem item = (ToolStripMenuItem)sender;
            if (item.Name == "CloseSolfOne")
            {
                CloseVideoSource(SlotNo.NoOne);
            }
            else if (item.Name == "CloseSolfTwo")
            {
                CloseVideoSource(SlotNo.NoTwo);
            }
            else if (item.Name == "CloseSolfThree")
            {
                CloseVideoSource(SlotNo.NoThree);
            }
        }

        private void FormMany_FormClosing(object sender, FormClosingEventArgs e)
        {
            CloseVideoSource(string.Empty);
        }

        // 关闭以前的视频信号源
        private void CloseVideoSource(string type)
        {
            //设置鼠标忙碌
            this.Cursor = Cursors.WaitCursor;

            // 停止当前信号
            if (type == SlotNo.NoOne)
            {
                videoSourcePlayerOne.SignalToStop();
                videoStop(videoSourcePlayerOne);
            }
            else if (type == SlotNo.NoTwo)
            {
                videoSourcePlayerTwo.SignalToStop();
                videoStop(videoSourcePlayerTwo);

                //设置摄像头属性
                vType = "1";
                menuStripThree.Enabled = false;
            }
            else if (type == SlotNo.NoThree)
            {
                videoSourcePlayerThree.SignalToStop();
                videoStop(videoSourcePlayerThree);

                menuStripThree.Enabled = false;
            }
            else//关闭
            {
                videoSourcePlayerOne.SignalToStop();
                videoStop(videoSourcePlayerOne);
                videoSourcePlayerTwo.SignalToStop();
                videoStop(videoSourcePlayerTwo);
                videoSourcePlayerThree.SignalToStop();
                videoStop(videoSourcePlayerThree);
            }

            // 停止计时
            if (!videoSourceOne.IsRunning)
                timer.Stop();

            //运动检测器复位
            if (detector != null)
                detector.Reset();

            this.Cursor = Cursors.Default;

            //清除
            Class.AVIWriteClass.AviWriteClass.Display();
        }

        private void videoStop(AForge.Controls.VideoSourcePlayer videoSourcePlay)
        {
            // 等待2秒，直到相机将停止
            for (int i = 0; (i < 50) && (videoSourcePlay.IsRunning); i++)
            {
                Thread.Sleep(100);
            }
            if (videoSourcePlay.IsRunning)
                videoSourcePlay.Stop();
            videoSourcePlay.BorderColor = Color.Black;
        }
        #endregion

        #region 视频每帧收集
        //imageone
        private void videoSourcePlayerOne_NewFrame(object sender, ref Bitmap imageone)
        {
            if (vType == "1")//1为单视频显示
            {
                float motionLevel = detector.ProcessFrame(imageone);//每帧的差异值

                //写入视频
                Class.AVIWriteClass.AviWriteClass.AVIWriteProcess(motionLevel, imageone);

                //Rectangle[] rc = monBlob.ObjectRectangles;
                //无动态变化不处理
                if (motionLevel == 0)
                {
                    return;
                }
                _lock.EnterWriteLock();

                RecBlobItems = monBlob.BlobCounter.GetObjectsInformation();//每帧区域集合

                try
                {
                    Thread.Sleep(200);
                    //处理人数
                    PeopleCount.ProcessPCount(RecBlobItems, ref AllCount);
                }
                finally
                {
                    _lock.ExitWriteLock();
                }
            }
            else
            {
                if (ImageOne == null)
                    ImageOne = (Bitmap)imageone.Clone();
            }
        }
        //imagetwo
        private void videoSourcePlayerTwo_NewFrame(object sender, ref Bitmap imagetwo)
        {
            // detector.ProcessFrame((Bitmap)imagetwo.Clone());
            if (ImageTwo == null)
                ImageTwo = (Bitmap)imagetwo.Clone();
        }
        //imagethree
        private void videoSourcePlayerThree_NewFrame(object sender, ref Bitmap imagethree)
        {
            //detector.ProcessFrame((Bitmap)imagethree.Clone());
            if (ImageThree == null)
                ImageThree = (Bitmap)imagethree.Clone();
        }
        #endregion

        #region 多视频处理合成
        void Process()
        {
            //单人视频不进行图片合成
            if (vType == "1") TheadReset.WaitOne();
            while (true)
            {
                if (!chkSing.Checked)
                {
                    #region 图片合成拼接
                    if (ImageOne == null || ImageTwo == null)
                    {
                        TheadReset.WaitOne();
                    }
                    else
                    {
                        if (pa.ImageOne == null || pa.ImageTwo == null || pa.ImageThree == null)
                        {
                            pa.Lock();
                            pa.ImageOne = ImageOne;
                            pa.ImageTwo = ImageTwo;
                            pa.ImageThree = ImageThree;
                            try
                            {
                                if (ckbMerger.Checked)//图片合成处理
                                {
                                    ImageBit = (Bitmap)pa.ImageMerger().Clone();
                                }
                                else
                                {
                                    ImageBit = (Bitmap)pa.ImagePanorama().Clone();
                                }

                            }
                            catch (Exception)
                            {
                                TheadReset.WaitOne();
                            }

                            pa.Unlock();

                            _lock.EnterReadLock();
                            Bitmap tmpShowImage = (Bitmap)ImageBit.Clone();
                            float motionLevel = detector.ProcessFrame(tmpShowImage);//每帧的差异值

                            //写视频
                            Class.AVIWriteClass.AviWriteClass.AVIWriteProcess(motionLevel, tmpShowImage);

                            RecBlobItems = monBlob.BlobCounter.GetObjectsInformation();//每帧区域集合

                            pictureBoxshow.Image = tmpShowImage;

                            if (motionLevel == 0)
                            {
                                return;
                            }
                            //计算图像人数
                            //处理人数
                            PeopleCount.ProcessPCount(RecBlobItems, ref AllCount);

                            _lock.ExitReadLock();
                            ImageDisplay();
                        }
                    }
                    #endregion
                }
                else
                {
                    #region 单独计算
                    float motionLevel = 0;
                    int peopleOne = 0;
                    int peopleTwo = 0;
                    int peopleThree = 0;
                    if (ImageOne == null)
                    {
                        motionLevel = detector.ProcessFrame(ImageOne);//每帧的差异值
                        RecBlobItems = monBlob.BlobCounter.GetObjectsInformation();//每帧区域集合
                        PeopleCount.ProcessPCountSing(RecBlobItems, ref peopleOne);
                    }
                    if (ImageTwo == null)
                    {
                        motionLevel = detector.ProcessFrame(ImageOne);//每帧的差异值
                        RecBlobItems = monBlob.BlobCounter.GetObjectsInformation();//每帧区域集合
                        PeopleCount.ProcessPCountSing(RecBlobItems, ref peopleTwo);
                    }
                    if (ImageThree == null)
                    {
                        motionLevel = detector.ProcessFrame(ImageOne);//每帧的差异值
                        RecBlobItems = monBlob.BlobCounter.GetObjectsInformation();//每帧区域集合
                        PeopleCount.ProcessPCountSing(RecBlobItems, ref peopleThree);
                    }
                    PeopleCountSing = peopleOne + peopleTwo + peopleThree;

                    XmlHelper.Insert("Time", "Count", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), PeopleCountSing.ToString());
                    //    StartTime = DateTime.Now;
                    #endregion
                }
            }
        }

        //清除
        private void ImageDisplay()
        {
            ImageOne = null;
            ImageTwo = null;
            ImageThree = null;
            pa.ImageOne = null;
            pa.ImageTwo = null;
            pa.ImageThree = null;
        }

        #endregion

        #region 定时处理
        private void timer_Tick(object sender, EventArgs e)
        {
            TheadReset.Set();

            labFps(SlotNo.NoOne, videoSourcePlayerOne);
            labFps(SlotNo.NoTwo, videoSourcePlayerTwo);
            labFps(SlotNo.NoThree, videoSourcePlayerThree);

            //显示数据
            if (tmpAllCount.Length == 0)
            {
                tmpAllCount = new int[AllCount.Length];
                AllCount.CopyTo(tmpAllCount, 0);
                AllCount = new int[] { };
                foreach (int item in tmpAllCount)
                {
                    ClearLbCount();
                    this.lbTime.Text = DateTime.Now.ToString("HH:mm:ss");
                    this.lbCount.Text = item.ToString();
                    //Thread.Sleep(100);
                    //MessageBox.Show(item.ToString());
                }
                tmpAllCount = new int[] { };
            }
            else//单图计算
            {
                ClearLbCount();
                this.lbTime.Text = DateTime.Now.ToString("HH:mm:ss");
                this.lbCount.Text =PeopleCountSing.ToString();
            }

            dataGridView1.DataSource = RecBlobItems;
        }

        void ClearLbCount()
        {
            this.lbTime.Text = string.Empty;
            this.lbCount.Text = string.Empty;
        }

        private void labFps(string type, AForge.Controls.VideoSourcePlayer videoSourcePlay)
        {
            IVideoSource videoSource = videoSourcePlay.VideoSource;

            if (videoSource != null && videoSource.IsRunning)
            {
                if (type == SlotNo.NoOne)
                    labFpsOne.Text = FpsCount.fpsResult(videoSource.FramesReceived).ToString("F2") + " fps";
                else if (type == SlotNo.NoTwo)
                    labFpsTwo.Text = FpsCount.fpsResult(videoSource.FramesReceived).ToString("F2") + " fps";
                else if (type == SlotNo.NoThree)
                    labFpsThree.Text = FpsCount.fpsResult(videoSource.FramesReceived).ToString("F2") + " fps";
            }
        }

        #endregion

        private void btnClearZero_Click(object sender, EventArgs e)
        {
            AllCount = new int[] { };
            lbCount.Text = "0";
        }

        #region 收集位图计算
        /// <summary>
        /// 收集位图位置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ckbComputer_CheckedChanged(object sender, EventArgs e)
        {
            if (ckbComputer.Checked)
            {
                Properties.Settings.Default.IsCollect = "1";//1记录位置
                Properties.Settings.Default.Save();
            }
            else
            {
                Properties.Settings.Default.IsCollect = "2";//2写入记录
                Properties.Settings.Default.Save();
            }
            btnComputer.Enabled = !ckbComputer.Checked;

            ckbMerger.Enabled = !ckbComputer.Checked;
        }
        /// <summary>
        /// 计算
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnComputer_Click(object sender, EventArgs e)
        {
            //
            txtControl.Read();

            Properties.Settings.Default.IsCollect = "0";//0正常记录
            Properties.Settings.Default.Save();

            this.btnComputer.Enabled = false;

            Properties.Settings.Default.Reload();
        }
        #endregion

        /// <summary>
        /// 合并图像 ckbMerger
        /// </summary>
        private void ckbMerger_CheckedChanged(object sender, EventArgs e)
        {
            btnComputer.Enabled = !ckbMerger.Checked;
            ckbComputer.Enabled = !ckbMerger.Checked;
        }
    }
}
